{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Naive Bayes Classifier"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Title: Understanding the Naive Bayes Classifier\n",
    "\n",
    "---\n",
    "\n",
    "#### **Introduction:**\n",
    "\n",
    "In the realm of machine learning and data science, the Naive Bayes classifier holds a pivotal role due to its simplicity, efficiency, and surprising power, especially in the field of text analysis. Named after the famous mathematician Thomas Bayes, the Naive Bayes classifier is a probabilistic machine learning model used for classification tasks.\n",
    "\n",
    "The Naive Bayes classifier is based on Bayes' theorem, which is an equation describing the relationship of conditional probabilities of statistical quantities. In Bayesian classification, we're interested in finding the probability of a label given some observed features, which we can express as P(L | features). Bayes' theorem tells us how to express this in terms of quantities we can compute more directly.\n",
    "\n",
    "A key assumption made by the Naive Bayes classifier, which is actually a simplification, is that the features are conditionally independent given the class. This means that the presence of a particular feature in a class is unrelated to the presence of any other feature in the same class. This is the 'naive' part of the 'Naive Bayes' - it's a naive assumption because it's not often encountered in real-world data, yet the classifier can perform surprisingly well even when this assumption doesn't hold.\n",
    "\n",
    "Naive Bayes classifiers are highly scalable and well-suited to high-dimensional datasets. They are often used for text classification, spam filtering, sentiment analysis, and recommendation systems, among other applications.\n",
    "\n",
    "In this article, we will delve deeper into the workings of the Naive Bayes classifier, explore its mathematical foundation, discuss its strengths and weaknesses, and see it in action through Python code examples.\n",
    "\n",
    "---\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# What is Naive Bayes Classifier?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Naive Bayes Classifier is a type of probabilistic machine learning model used for classification tasks. The classifier is based on applying Bayes' theorem with strong (naive) independence assumptions between the features.\n",
    "\n",
    "In simple terms, a Naive Bayes classifier assumes that the presence (or absence) of a particular feature of a class is unrelated to the presence (or absence) of any other feature, given the class variable. For example, a fruit may be considered an apple if it is red, round, and about 3 inches in diameter. A Naive Bayes classifier considers each of these features (red, round, 3 inches in diameter) to contribute independently to the probability that the fruit is an apple, regardless of any possible correlations between color, roundness, and diameter.\n",
    "\n",
    "Naive Bayes classifiers are highly scalable and are known to outperform even highly sophisticated classification methods. They are particularly well suited for high-dimensional data sets and are commonly used in text categorization (spam or not spam), sentiment analysis, and document classification. Despite their naive design and oversimplified assumptions, Naive Bayes classifiers often perform very well in many complex real-world situations.\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# What Is the Naive Bayes Algorithm?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Naive Bayes algorithm is a classification technique based on applying Bayes' theorem with a strong assumption of independence among predictors. In simple terms, a Naive Bayes classifier assumes that the presence of a particular feature in a class is unrelated to the presence of any other feature.\n",
    "\n",
    "Here's a step-by-step breakdown of how the Naive Bayes algorithm works:\n",
    "\n",
    "1. **Convert the data set into a frequency table**\n",
    "2. **Create a likelihood table by finding the probabilities of given observations**\n",
    "3. **Now, use Bayes theorem to calculate the posterior probability.**\n",
    "\n",
    "The core idea is that the predictors contribute independently to the probability of the class. This independent contribution is where the term 'naive' comes from.\n",
    "\n",
    "The Naive Bayes model is easy to build and particularly useful for very large data sets. Along with simplicity, Naive Bayes is known to outperform even highly sophisticated classification methods. It is widely used in text analytics, spam filtering, recommendation systems, and more.\n",
    "\n",
    "Despite its simplicity, the Naive Bayes algorithm often performs well and is widely used because it often outputs a classification model that classifies correctly even when its assumption of the independence of features is violated."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Realife Example of Naive Bayes Algorithm\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here are a few real-life examples of where the Naive Bayes algorithm is commonly used:\n",
    "\n",
    "1. **Email Spam Filtering**: Naive Bayes is a popular algorithm for email spam filtering. It classifies emails as 'spam' or 'not spam' by examining the frequency of certain words and phrases. For example, emails containing the words 'lottery', 'win', or 'claim' might be classified as spam.\n",
    "\n",
    "2. **Sentiment Analysis**: Naive Bayes is often used in sentiment analysis to determine whether a given piece of text (like a product review or a tweet) is positive, negative, or neutral. It does this by looking at the words used in the text and their associated sentiments.\n",
    "\n",
    "3. **Document Categorization**: Naive Bayes can be used to categorize documents into different categories based on their content. For example, news articles might be categorized into 'sports', 'politics', 'entertainment', etc.\n",
    "\n",
    "4. **Healthcare**: In healthcare, Naive Bayes can be used to predict the likelihood of a patient having a particular disease based on their symptoms.\n",
    "\n",
    "5. **Recommendation Systems**: Naive Bayes can be used in recommendation systems to predict a user's interests and recommend products or services. For example, if a user often watches action movies, the system might recommend other action movies for them to watch.\n",
    "\n",
    "Remember, the 'naive' assumption of Naive Bayes (that all features are independent given the class) is often violated in real-world data, yet the algorithm often performs surprisingly well."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Bayes' Theorem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Bayes' theorem is a fundamental principle in the field of statistics and probability. It describes the relationship of conditional probabilities of statistical quantities. In other words, it gives us a way to update our previous beliefs based on new evidence.\n",
    "\n",
    "The theorem is named after Thomas Bayes, who first provided an equation that allows new evidence to update beliefs in his \"An Essay towards solving a Problem in the Doctrine of Chances\" (1763). It's articulated as:\n",
    "\n",
    "P(A|B) = [P(B|A) * P(A)] / P(B)\n",
    "\n",
    "Where:\n",
    "\n",
    "- P(A|B) is the posterior probability of A given B. It's what we are trying to estimate.\n",
    "- P(B|A) is the likelihood, the probability of observing B given A.\n",
    "- P(A) is the prior probability of A. It's our belief about A before observing B.\n",
    "- P(B) is the marginal likelihood of B.\n",
    "\n",
    "In the context of a classification problem, we can understand it as follows:\n",
    "\n",
    "- A is the event that a given data point belongs to a certain class.\n",
    "- B is the observed features of the data point.\n",
    "- P(A|B) is then the probability that the data point belongs to that class given its features.\n",
    "\n",
    "Bayes' theorem thus provides a way to calculate the probability of a data point belonging to a certain class based on its features, which is the fundamental idea behind the Naive Bayes classifier."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# What are the steps involved in training a Naive Bayes classifier?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Training a Naive Bayes classifier involves several steps:\n",
    "\n",
    "1. **Data Preprocessing**: The first step in training a Naive Bayes classifier is to preprocess the data. This may involve cleaning the data, handling missing values, encoding categorical variables, and normalizing numerical variables.\n",
    "\n",
    "2. **Feature Extraction**: Depending on the type of data, you might need to extract features that the classifier can use. For example, if you're classifying text documents, you might need to convert the documents into a bag-of-words representation or a TF-IDF representation.\n",
    "\n",
    "3. **Train-Test Split**: Split your dataset into a training set and a test set. The training set is used to train the model, and the test set is used to evaluate its performance.\n",
    "\n",
    "4. **Model Training**: Train the Naive Bayes classifier on the training data. This involves calculating the prior probabilities (the probabilities of each class) and the likelihoods (the probabilities of each feature given each class).\n",
    "\n",
    "5. **Prediction**: Use the trained model to make predictions on unseen data. For each data point, the model calculates the posterior probability of each class given the features of the data point, and assigns the data point to the class with the highest posterior probability.\n",
    "\n",
    "6. **Evaluation**: Evaluate the performance of the model on the test set. Common evaluation metrics for classification tasks include accuracy, precision, recall, and the F1 score.\n",
    "\n",
    "7. **Model Tuning**: Depending on the performance of the model, you might need to go back and adjust the model's parameters, choose different features, or preprocess the data in a different way. This is an iterative process.\n",
    "\n",
    "Remember, the 'naive' assumption of Naive Bayes (that all features are independent given the class) is often violated in real-world data, yet the algorithm often performs surprisingly well."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# How Do Naive Bayes Algorithms Work?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Naive Bayes algorithms are based on Bayes' theorem, which is a way of finding a probability when we know certain other probabilities. The 'naive' part comes from the assumption that each input (feature) is independent of the others.\n",
    "\n",
    "Let's consider a simple example related to weather conditions. Suppose we are trying to predict whether a person will go for a walk based on the weather conditions. We have the following data:\n",
    "\n",
    "- 60% of the days are sunny.\n",
    "- The person goes for a walk on 70% of the sunny days.\n",
    "- The person goes for a walk on 40% of the days.\n",
    "\n",
    "We want to find out the probability that it is sunny given that the person went for a walk. This is written as P(Sunny|Walk).\n",
    "\n",
    "Using Bayes' theorem:\n",
    "\n",
    "P(Sunny|Walk) = [P(Walk|Sunny) * P(Sunny)] / P(Walk)\n",
    "\n",
    "We can substitute the known values into this equation:\n",
    "\n",
    "P(Sunny|Walk) = [(0.7) * (0.6)] / (0.4) = 1.05\n",
    "\n",
    "However, a probability cannot be greater than 1. This discrepancy arises because the actual probability of the person going for a walk (P(Walk)) is not independent of the weather conditions. The correct value of P(Walk) should be the total probability of the person going for a walk under all weather conditions, which is calculated as follows:\n",
    "\n",
    "P(Walk) = P(Walk and Sunny) + P(Walk and not Sunny)\n",
    "        = P(Walk|Sunny) * P(Sunny) + P(Walk|not Sunny) * P(not Sunny)\n",
    "        = (0.7 * 0.6) + (0.3 * 0.4) = 0.42 + 0.12 = 0.54\n",
    "\n",
    "Substituting the correct value of P(Walk) into Bayes' theorem gives:\n",
    "\n",
    "P(Sunny|Walk) = [(0.7) * (0.6)] / (0.54) = 0.777...\n",
    "\n",
    "So, the updated probability that it is sunny given that the person went for a walk is approximately 0.78, or 78%.\n",
    "\n",
    "This example demonstrates how Naive Bayes updates our beliefs based on evidence (in this case, the fact that the person went for a walk). However, it also shows why the 'naive' assumption can lead to errors if the input features are not truly independent."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Python Code Implementation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's an example of how you might use the Naive Bayes algorithm to classify emails as spam or not spam. This example uses the `sklearn` library in Python.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "vscode": {
     "languageId": "r"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "    not spam       0.00      0.00      0.00       0.0\n",
      "        spam       0.00      0.00      0.00       1.0\n",
      "\n",
      "    accuracy                           0.00       1.0\n",
      "   macro avg       0.00      0.00      0.00       1.0\n",
      "weighted avg       0.00      0.00      0.00       1.0\n",
      "\n"
     ]
    }
   ],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.feature_extraction.text import CountVectorizer\n",
    "from sklearn.naive_bayes import MultinomialNB\n",
    "from sklearn import metrics\n",
    "from warnings import filterwarnings\n",
    "\n",
    "filterwarnings('ignore')\n",
    "\n",
    "# Sample data\n",
    "emails = ['Hey, can we meet tomorrow?', 'Upto 20% discount, exclusive offer just for you', \n",
    "          'Are you available tomorrow?', 'Win a lottery of $1 Million']\n",
    "labels = ['not spam', 'spam', 'not spam', 'spam']\n",
    "\n",
    "# Convert emails to word count vectors\n",
    "vectorizer = CountVectorizer()\n",
    "email_vec = vectorizer.fit_transform(emails)\n",
    "\n",
    "# Split data into training and test sets\n",
    "X_train, X_test, y_train, y_test = train_test_split(email_vec, labels, test_size=0.2, random_state=1)\n",
    "\n",
    "# Train a Naive Bayes classifier\n",
    "nb = MultinomialNB()\n",
    "nb.fit(X_train, y_train)\n",
    "\n",
    "# Make predictions on the test set\n",
    "predictions = nb.predict(X_test)\n",
    "\n",
    "# Evaluate the model\n",
    "print(metrics.classification_report(y_test, predictions))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "In this example, we first convert the emails into word count vectors using `CountVectorizer`. This transforms the text such that each email becomes a vector in a high-dimensional space, where each dimension corresponds to a unique word in all the emails.\n",
    "\n",
    "We then split the data into a training set and a test set using `train_test_split`.\n",
    "\n",
    "Next, we create a `MultinomialNB` object, which is a Naive Bayes classifier for multinomial models. We train this classifier on the training data using the `fit` method.\n",
    "\n",
    "Finally, we use the trained classifier to make predictions on the test set, and we evaluate the performance of the classifier using `classification_report`, which prints precision, recall, F1-score, and support for each class."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# R Code Implementation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here's an example of how you might use the Naive Bayes classifier in R using the `e1071` package. This example uses the built-in `iris` dataset.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "vscode": {
     "languageId": "r"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Installing package into ‘/home/blackheart/R/x86_64-pc-linux-gnu-library/4.1’\n",
      "(as ‘lib’ is unspecified)\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "            true\n",
      "pred         setosa versicolor virginica\n",
      "  setosa         14          0         0\n",
      "  versicolor      0         18         0\n",
      "  virginica       0          0        13\n"
     ]
    }
   ],
   "source": [
    "# Load the necessary library\n",
    "install.packages(\"e1071\")\n",
    "library(e1071)\n",
    "\n",
    "# Load the iris dataset\n",
    "data(iris)\n",
    "\n",
    "# Split the data into training and test sets\n",
    "set.seed(123)\n",
    "train_indices <- sample(1:nrow(iris), nrow(iris)*0.7)\n",
    "train_data <- iris[train_indices, ]\n",
    "test_data <- iris[-train_indices, ]\n",
    "\n",
    "# Train a Naive Bayes classifier\n",
    "model <- naiveBayes(Species ~ ., data = train_data)\n",
    "\n",
    "# Make predictions on the test set\n",
    "predictions <- predict(model, test_data)\n",
    "\n",
    "# Print out the confusion matrix to see how well the model did\n",
    "print(table(pred = predictions, true = test_data$Species))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "\n",
    "In this example, we first load the `e1071` library, which provides the `naiveBayes` function. We then load the `iris` dataset and split it into a training set and a test set.\n",
    "\n",
    "Next, we train a Naive Bayes classifier on the training data using the `naiveBayes` function. The formula `Species ~ .` tells the function to use `Species` as the dependent variable and all other variables in the data frame as independent variables.\n",
    "\n",
    "Finally, we use the trained classifier to make predictions on the test set, and we print out a confusion matrix to see how well the model did. The confusion matrix shows the number of correct and incorrect predictions made by the classifier, broken down by each class."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# What are the different types of Naive Bayes classifiers?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are several types of Naive Bayes classifiers, each suited to a different type of input data:\n",
    "\n",
    "1. **Gaussian Naive Bayes**: This is the most common type. It assumes that the data for each class is distributed according to a Gaussian (normal) distribution. It's often used when the features are continuous.\n",
    "\n",
    "2. **Multinomial Naive Bayes**: This is used when the data are discrete counts, such as the number of times a particular word appears in a document. It's often used in text classification problems.\n",
    "\n",
    "3. **Bernoulli Naive Bayes**: This is used when the features are binary (0/1). It's also often used in text classification, where the features might be whether or not a particular word appears in a document.\n",
    "\n",
    "4. **Complement Naive Bayes**: This is a variation of Multinomial Naive Bayes that is particularly suited for imbalanced data sets. Instead of modeling the data with respect to each class, it models the data with respect to all classes that are not in the current class.\n",
    "\n",
    "5. **Categorical Naive Bayes**: This is used for categorical data. Each feature is assumed to be a categorical variable.\n",
    "\n",
    "Each of these types makes a different assumption about the distribution of the data, and the best one to use depends on the specific problem and data set."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# What are the advantages and disadvantages of using the Naive Bayes classifier?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Advantages of Naive Bayes Classifier:\n",
    "\n",
    "1. **Efficiency**: Naive Bayes requires a small amount of training data to estimate the necessary parameters. It's fast and easy to predict the class of the test dataset.\n",
    "\n",
    "2. **Easy to implement**: Naive Bayes is simple to understand and easy to implement. It's a good choice as a baseline model to compare with more complex models.\n",
    "\n",
    "3. **Works well with high dimensions**: Naive Bayes performs well when dealing with many input variables. It's often used for text classification where the number of input variables (words) can be large.\n",
    "\n",
    "4. **Handles continuous and discrete data**: Naive Bayes can handle both continuous and discrete data. Different types of Naive Bayes classifiers can be used depending on the distribution of the data (Gaussian, Multinomial, Bernoulli).\n",
    "\n",
    "Disadvantages of Naive Bayes Classifier:\n",
    "\n",
    "1. **Assumption of independent predictors**: Naive Bayes assumes that all features are independent. In real life, it's almost impossible that we get a set of predictors which are completely independent.\n",
    "\n",
    "2. **Zero Frequency**: If the category of any categorical variable is not observed in training data set, then the model will assign a zero probability to that category and then a prediction cannot be made. This is often known as “Zero Frequency”. To solve this, we can use the smoothing technique. One of the simplest smoothing techniques is called Laplace estimation.\n",
    "\n",
    "3. **Bad estimator**: While Naive Bayes is a good classifier, it is known to be a bad estimator. So the probability outputs from `predict_proba` are not to be taken too seriously.\n",
    "\n",
    "4. **Data scarcity**: For data with a categorical variable, the estimation of probabilities can be a problem if a category has not been observed in the training data set."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# What are some common applications of the Naive Bayes classifier in real-world scenarios?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Naive Bayes classifiers have a wide range of applications due to their simplicity, efficiency, and relatively high accuracy. Here are some common real-world applications:\n",
    "\n",
    "1. **Email Spam Filtering**: Naive Bayes is one of the most popular algorithms for spam filtering. It classifies emails as 'spam' or 'not spam' by examining the frequency of certain words and phrases.\n",
    "\n",
    "2. **Sentiment Analysis**: Naive Bayes is often used in sentiment analysis to determine whether a given piece of text (like a product review or a tweet) is positive, negative, or neutral. It does this by looking at the words used in the text and their associated sentiments.\n",
    "\n",
    "3. **Document Categorization**: Naive Bayes can be used to categorize documents into different categories based on their content. For example, news articles might be categorized into 'sports', 'politics', 'entertainment', etc.\n",
    "\n",
    "4. **Healthcare**: In healthcare, Naive Bayes can be used to predict the likelihood of a patient having a particular disease based on their symptoms.\n",
    "\n",
    "5. **Recommendation Systems**: Naive Bayes can be used in recommendation systems to predict a user's interests and recommend products or services. For example, if a user often watches action movies, the system might recommend other action movies for them to watch.\n",
    "\n",
    "6. **Text Classification**: Naive Bayes is widely used in text classification, where the data are typically represented as word vector counts (although tf-idf vectors are also commonly used in text classification).\n",
    "\n",
    "7. **Fraud Detection**: In finance, Naive Bayes is used for credit scoring, predicting loan defaults, and fraud detection in transactions."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Tips to Improve the Power of the NB Model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here are some tips to improve the performance of a Naive Bayes model:\n",
    "\n",
    "1. **Feature Selection**: Naive Bayes assumes that all features are independent. If some features are dependent on each other, the prediction might be incorrect. So, it's important to select only the relevant features.\n",
    "\n",
    "2. **Avoid Zero Frequency**: If a given class and feature value never occur together in the training data, then the frequency-based probability estimate will be zero. To solve this, we can use a smoothing technique. One of the simplest smoothing techniques is called Laplace estimation.\n",
    "\n",
    "3. **Tune the Model**: Use grid search or random search to find the optimal parameters for the Naive Bayes model. For example, in the case of the Gaussian Naive Bayes, you can adjust the `var_smoothing` parameter.\n",
    "\n",
    "4. **Preprocess Your Data**: Techniques such as removing outliers, filling missing values, and scaling can help improve the performance of a Naive Bayes model.\n",
    "\n",
    "5. **Use the Right Variant of Naive Bayes**: Different variants of Naive Bayes (like Gaussian, Multinomial, Bernoulli) are suitable for different types of data. Choose the one that's most appropriate for your data.\n",
    "\n",
    "6. **Ensemble Methods**: Combining the predictions of multiple different models can often result in better performance than any single model. You could consider using a Naive Bayes model as part of an ensemble.\n",
    "\n",
    "7. **Update Your Model**: Naive Bayes allows for incremental learning. As new data comes in, you can update your model's probabilities without having to retrain it from scratch.\n",
    "\n",
    "Remember, while Naive Bayes is a powerful tool, it's not always the best choice for every problem. Depending on the complexity and nature of your data, other models may yield better results."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Reference\n",
    "\n",
    "1. [analyticsvidya.com](https://www.analyticsvidhya.com/blog/2017/09/naive-bayes-explained/)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# **Thank You!**"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "R",
   "language": "R",
   "name": "ir"
  },
  "language_info": {
   "codemirror_mode": "r",
   "file_extension": ".r",
   "mimetype": "text/x-r-source",
   "name": "R",
   "pygments_lexer": "r",
   "version": "4.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
